#ifndef	MEMENV_H
#define	MEMENV_H

#include <stdint.h>
#include <stdlib.h>
#include <string.h>

struct	memenv {
	uint32_t	menv_cur;
	uint32_t	menv_max;
	void*		menv_base;
};

#define	INVALID_OBJ_IDX	(0xffffffff)
#define	MENV_INIT(e)			do {				\
	memset((e), 0, sizeof(*(e)));					\
} while (0)

#define	MENV_ALLOC_OBJ(e, p, sz)	do {				\
	uint32_t	__c = (e)->menv_cur + (sz);			\
	if (__c > (e)->menv_max) {					\
		void*	__rb;						\
		uint32_t	__ns = __c + ((sz) >> 3) + 32;		\
		__rb = realloc((e)->menv_base, __ns);			\
		if (__rb == NULL) {					\
			(p) = INVALID_OBJ_IDX;				\
			break;						\
		}							\
		(e)->menv_max = __ns;					\
		(e)->menv_base = __rb;					\
	}								\
	(p) = (e)->menv_cur >> 2;					\
	(e)->menv_cur = __c;						\
} while (0)

#define	MENV_GET_OBJ(e, p)	((void*)((uint32_t*)((e)->menv_base) + (p)))

#define	MENV_FINI(e)			do {				\
	free((e)->menv_base);						\
	memset((e), 0, sizeof(*(e)));					\
} while (0)

#endif	/* !MEMENV_H */

